/**
 * 
 */
package fr.upvm.lem3.vm3d.ui.swing.menu;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;

import fr.upvm.lem3.vm3d.ui.swing.frontend.MainGUI;


/** Menubar of the maingui
 * @author Nougouapi
 *
 */
public class MyMenuBar extends JMenuBar implements ActionListener, ItemListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6656675918199252009L;
	
	/**
	 * static text to set for the menus and menu items
	 */
	private final static String FILE_M = "File";
	private final static String FILE_SBM_OPEN = "Open";
	private final static String FILE_SBM_PRINT = "Print";
	private final static String FILE_SBM_PRINT_TOOLTIPP = "Outputs current volume as a pdf file";
	private final static String FILE_SBM_EXIT = "Exit";
	
	private final static String VIEW_M= "View";	
	private final static String VIEW_M_LOOKAN_AND_FEEL = "Look & Feel";
	private final static String SBM_SYSTEM = "System";
	private final static String SBM_METAL = "Metal";
	private final static String SBM_MOTIF = "Motif";
	private final static String VIEW_M_TOOLBARS = "Toolbars";
	private final static String SBM_MAIN_CONTROLS = "Main controls";
	private final static String SBM_COMMON = "Common";
	private final static String VIEW_SBM_PIPELINE_BROWSER = "Pipeline Browser";
	private final static String VIEW_SBM_OBJECT_INSPECTOR = "Object Inspector";
	
	private final static String HELP_M = "Help";
	private final static String HELP_SBM_INFO= "Info";
	
	private JFrame parentFrame;      		// frame on that this menuBar object will place on
	private MyMenuBarController controller;
	
	/**
	 * Variables for the menus
	 */
	private JMenu menuFile;
	private JMenu menuView;
	private JMenu menuHelp;
	
	private JMenuItem menuItemPipelineBrowser;
	private JMenuItem menuItemObjectInspector;
	
	MyMouseAdpter adapter = null;
	ButtonGroup btnGroup;
	/**
	 * constructor
	 * @param frame
	 */
	public MyMenuBar(JFrame frame){
		super();
		this.parentFrame=frame;
		this.setController(new MyMenuBarController(this));
		adapter = new MyMouseAdpter();
		initComponents();
	}
	/**
	 * initialize the menuBar
	 */
	private void initComponents(){
		btnGroup = new ButtonGroup();
		add(getMenuFile());
		add(getMenuView());
		add(getMenuHelp());
	}
	/**
	 * @param parentFrame the parentFrame to set
	 */
	public void setParentFrame(JFrame parentFrame) {
		this.parentFrame = parentFrame;
	}
	/**
	 * @return the parentFrame
	 */
	public JFrame getParentFrame() {
		return parentFrame;
	}
	/**
	 * @return the menuFile
	 */
	public JMenu getMenuFile() {
		if (menuFile == null){
			menuFile = createMenu(FILE_M, KeyEvent.VK_F, adapter);
			//add the menu items
			menuFile.add(createMenuItem(FILE_SBM_OPEN, KeyEvent.VK_O, KeyEvent.VK_O, ActionEvent.CTRL_MASK, this));
			menuFile.addSeparator();
			JMenuItem menuItemPrint = createMenuItem(FILE_SBM_PRINT, KeyEvent.VK_P,KeyEvent.VK_P,ActionEvent.CTRL_MASK,  this);
			menuItemPrint.setToolTipText(FILE_SBM_PRINT_TOOLTIPP);
			menuFile.add(menuItemPrint);
			menuFile.addSeparator();
			menuFile.add(createMenuItem(FILE_SBM_EXIT, KeyEvent.VK_Q, KeyEvent.VK_Q, ActionEvent.CTRL_MASK, this));
		}
		return menuFile;
	}
	/**
	 * @param menuFile the menuFile to set
	 */
	public  void setMenuFile(JMenu menuFile) {
		this.menuFile = menuFile;
	}
	/**
	 * @return the menuView
	 */
	public final JMenu getMenuView() {
		if(menuView == null){
			menuView = createMenu(VIEW_M, KeyEvent.VK_V, adapter);
			/**
			 * Submenu Look and Feel
			 */
			JMenu lf_Submenu = createMenu(VIEW_M_LOOKAN_AND_FEEL, KeyEvent.VK_L);
			lf_Submenu.add(createRadioBtnMenuItem(SBM_SYSTEM,KeyEvent.VK_S, true, btnGroup, this));
			lf_Submenu.add(createRadioBtnMenuItem(SBM_METAL,KeyEvent.VK_M, false, btnGroup, this));
			lf_Submenu.add(createRadioBtnMenuItem(SBM_MOTIF,KeyEvent.VK_M, false, btnGroup, this));
			//add this menu as submenu to the view menu
			menuView.add(lf_Submenu);
			menuView.addSeparator();
			/**
			 * Submenu Toolbars
			 */
			JMenu tlb_Submenu = createMenu(VIEW_M_TOOLBARS, KeyEvent.VK_T);
			tlb_Submenu.add(createCbMenuItem(SBM_MAIN_CONTROLS, KeyEvent.VK_M,true,this));
			tlb_Submenu.add(createCbMenuItem(SBM_COMMON, KeyEvent.VK_C, false,this));
			menuView.add(tlb_Submenu);
			menuView.addSeparator();
			/**
			 * Adding the others menu items
			 */
			menuView.add(getMenuItemObjectInspector());
			menuView.add(getMenuItemPipelineBrowser()); 		
		}
		return menuView;
	}
	/**
	 * @param menuView the menuView to set
	 */
	public final void setMenuView(JMenu menuView) {
		this.menuView = menuView;
	}
	/**
	 * @return the menuHelp
	 */
	public final JMenu getMenuHelp() {
		if(menuHelp == null){
			menuHelp = createMenu(HELP_M, KeyEvent.VK_H, adapter);
			menuHelp.add(createMenuItem(HELP_SBM_INFO, KeyEvent.VK_I, this));
		}
		return menuHelp;
	}
	/**
	 * @param menuHelp the menuHelp to set
	 */
	public final void setMenuHelp(JMenu menuHelp) {
		this.menuHelp = menuHelp;
	}
	/**
	 * @return the menuItemPipelineBrowser
	 */
	public final JMenuItem getMenuItemPipelineBrowser() {
		if(menuItemPipelineBrowser == null){
			menuItemPipelineBrowser = createCbMenuItem(VIEW_SBM_PIPELINE_BROWSER, KeyEvent.VK_P, KeyEvent.VK_P, ActionEvent.ALT_MASK, false, this);
		}
		return menuItemPipelineBrowser;
	}
	/**
	 * @param menuItemPipelineBrowser the menuItemPipelineBrowser to set
	 */
	public final void setMenuItemPipelineBrowser(JMenuItem menuItemPipelineBrowser) {
		this.menuItemPipelineBrowser = menuItemPipelineBrowser;
	}
	/**
	 * @return the menuItemObjectInspector
	 */
	public final JMenuItem getMenuItemObjectInspector() {
		if(menuItemObjectInspector == null){
			menuItemObjectInspector = createCbMenuItem(VIEW_SBM_OBJECT_INSPECTOR, KeyEvent.VK_O, KeyEvent.VK_O, ActionEvent.ALT_MASK, true, this);
		}
		return menuItemObjectInspector;
	}
	/**
	 * @param menuItemObjectInspector the menuItemObjectInspector to set
	 */
	public final void setMenuItemObjectInspector(JMenuItem menuItemObjectInspector) {
		this.menuItemObjectInspector = menuItemObjectInspector;
	}
	/**
	 * @return the controller
	 */
	public MyMenuBarController getController() {
		return controller;
	}
	/**
	 * @param controller the controller to set
	 */
	public void setController(MyMenuBarController controller) {
		this.controller = controller;
	}

	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param listener
	 * @return
	 */
	private JMenu createMenu(String text, int mnemonic, MouseAdapter listener){
		JMenu menu = new JMenu(text);
	    menu.setMnemonic(mnemonic);
	    menu.getAccessibleContext().setAccessibleDescription(text);
	    if ( listener != null) {
	    	menu.addMouseListener(listener);	    		    	
	    }
	    menu.setBorder(BorderFactory. createEmptyBorder(1,1,1,1));   //menu borders will be empty
	    return menu;
	}
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @return
	 */
	private JMenu createMenu(String text, int mnemonic){
		JMenu menu = new JMenu(text);
	    menu.setMnemonic(mnemonic);
	    menu.getAccessibleContext().setAccessibleDescription(text);
	    return menu;
	}
	
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param keyCode
	 * @param modifiers
	 * @param listener
	 * @return
	 */
	private JMenuItem createMenuItem(String text, int mnemonic, int keyCode, int modifiers, ActionListener listener){
		JMenuItem item = new JMenuItem(text, mnemonic);
		item.setAccelerator(KeyStroke.getKeyStroke(keyCode, modifiers));
		item.getAccessibleContext().setAccessibleDescription(text);
		item.addActionListener(listener);
		item.setActionCommand(text);
		return item;
	}
	
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param listener
	 * @return
	 */
	private JMenuItem createMenuItem(String text, int mnemonic, ActionListener listener){
		JMenuItem item = new JMenuItem(text, mnemonic);
		item.getAccessibleContext().setAccessibleDescription(text);
		item.addActionListener(listener);
		item.setActionCommand(text);
		return item;
	}
	
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param selected
	 * @return
	 */
	@SuppressWarnings("unused")
	private JRadioButtonMenuItem createRadioBtnMenuItem(String text, int mnemonic, boolean selected, ActionListener listener){
		 JRadioButtonMenuItem item = new JRadioButtonMenuItem(text);
		 item.setSelected(selected);
		 item.setMnemonic(mnemonic);
	     item.addActionListener(listener);
	     item.setActionCommand(text);
	     return item;
	}
	
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param selected
	 * @param btnGroup
	 * @param listener
	 * @return
	 */
	private JRadioButtonMenuItem createRadioBtnMenuItem(String text, int mnemonic, boolean selected,  ButtonGroup btnGroup, ActionListener listener){
		 JRadioButtonMenuItem item = new JRadioButtonMenuItem(text);
		 item.setSelected(selected);
		 item.setMnemonic(mnemonic);
		 item.addActionListener(listener);
		 item.setActionCommand(text);
		 btnGroup.add(item);         	//add the radio button into the given button group object
	     return item;
	}
	
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param listener
	 * @return
	 */
	private JCheckBoxMenuItem createCbMenuItem(String text, int mnemonic,boolean selected, ItemListener listener){
		 JCheckBoxMenuItem item = new JCheckBoxMenuItem(text);
		 item.setSelected(selected);
		 item.setMnemonic(mnemonic);
		 item.addItemListener(listener);
	     return item;
	}
	
	/**
	 * 
	 * @param text
	 * @param mnemonic
	 * @param keyCode
	 * @param modifiers
	 * @param listener
	 * @return
	 */
	private JCheckBoxMenuItem createCbMenuItem(String text, int mnemonic,int keyCode, int modifiers, boolean selected, ItemListener listener){
		 JCheckBoxMenuItem item = new JCheckBoxMenuItem(text);
		 item.setSelected(selected);
		 item.setMnemonic(mnemonic);
		 item.setAccelerator(KeyStroke.getKeyStroke(keyCode, modifiers));
		 item.addItemListener(listener);
	     return item;
	}

	/**
	 * perform the action over the menu items
	 */
	public void actionPerformed(ActionEvent e) {
//		JMenuItem source=(JMenuItem)(e.getSource());
		String cmd = e.getActionCommand();
		
		switch (cmd) {
		case FILE_SBM_OPEN: 
					((MainGUI)getParentFrame()).displayDataLoader(); //get the dataLoader window visible
					break;
		case FILE_SBM_PRINT:
					System.out.println ("Print out the current view as pdf file");
					((MainGUI)getParentFrame()).printCanvas();
					break;
		case FILE_SBM_EXIT:
					getController().systemExit();
					break;
		case SBM_SYSTEM:
					getController().setLookAndFeel(0);
					break;
		case SBM_METAL:
					getController().setLookAndFeel(1);
					break;
		case SBM_MOTIF:
					getController().setLookAndFeel(2);
					break;
		case HELP_SBM_INFO:
					getController().showInfoMsg();
					break;
		default:
			//Just leave the statement. Don't do anything
			break;
		}	
	}
	
	@Override
	public void itemStateChanged(ItemEvent e) {
		JCheckBoxMenuItem src = (JCheckBoxMenuItem)(e.getSource());
		MainGUI mFrame = (MainGUI)getParentFrame();
		/**
		 * display and hide the corresponding panel or container
		 */
		switch (src.getText()) {
		case SBM_MAIN_CONTROLS:
			if(src.isSelected()){
				mFrame.getController().showHideToolbar(mFrame.getControls_Toolbar(), true);
			}else{
				mFrame.getController().showHideToolbar(mFrame.getControls_Toolbar(), false);
			}
			break;
		case SBM_COMMON:
			if(src.isSelected()){
				mFrame.getController().showHideToolbar(mFrame.getCommon_Toolbar(), true);
			}else{
				mFrame.getController().showHideToolbar(mFrame.getCommon_Toolbar(), false);
			}
			break;
		case VIEW_SBM_PIPELINE_BROWSER:
			if(src.isSelected()){
				mFrame.getController().showHideToolbar(mFrame.getInternalPipeline(), true);
			}else{
				mFrame.getController().showHideToolbar(mFrame.getInternalPipeline(), false);
			}
			mFrame.getController().adjustSplitpane(this);
			break;
		case VIEW_SBM_OBJECT_INSPECTOR:
			if(src.isSelected()){
				mFrame.getController().showHideToolbar(mFrame.getInternalInspector(), true);
			}else{
				mFrame.getController().showHideToolbar(mFrame.getInternalInspector(), false);
			}
			mFrame.getController().adjustSplitpane(this);
			break;
		default:
			break;
		}
		
	}
	/**
	 * handle the action occurred when the state of the checkBox items changed 
	 */
	
	/**
	 * Internal adapter class  to handle the incoming events from the mouse
	 *******************************************************************
	 *MyMenuBar.java
	 *15.02.2012
	 *@author Guy Nougouapi
	 *******************************************************************
	 *
	 *******************************************************************
	 */
	class MyMouseAdpter extends MouseAdapter{
		
		public MyMouseAdpter() {}
		
		@Override
	    public void mouseEntered(MouseEvent e) {
			((JMenu)e.getSource()).setBorder(BorderFactory.createLineBorder(Color.lightGray, 1, true));
		}

	    @Override
	    public void mouseExited(MouseEvent e) {
	    	((JMenu)e.getSource()).setBorder(BorderFactory. createEmptyBorder(1,1,1,1));
	    }
	}
}
